import type { Directive, DirectiveBinding } from 'vue'

const map = new WeakMap() //创建映射关系
let distance = 100 //默认动画发生位置
let time = 500 //默认动画时间

// 创建观察对象 元素在视口中时播放动画
const ob = new IntersectionObserver((entries) => {
  for (const entry of entries) {
    const animation = map.get(entry.target)
    if (entry.isIntersecting) {
      // 该元素出现在视口中
      animation.play()
      ob.unobserve(entry.target)
    }
  }
})

// 判断元素 初始位置是否在视口中
const isBelowViewport = (el: any, distance: any) => {
  const rect = el.getBoundingClientRect()
  return rect.top - distance > window.innerHeight
}

interface ElType extends HTMLElement {
  __handleClick__: () => any
}

const slideIn: Directive = {
  mounted(el: ElType, binding?: DirectiveBinding) {
    if (binding?.value) {
      if (binding.value.time == 0) return
      binding.value.distance ? (distance = binding.value.distance) : distance
      binding.value.time ? (time = binding.value.time) : time
    }
    if (!isBelowViewport(el, distance)) {
      return
    }
    const animation = el.animate(
      [
        // 关键帧
        {
          transform: `translateY(${distance}px)`,
          opacity: 0.5,
          scale: 0.5,
        },
        {
          transform: `translateY(0)`,
          opacity: 1,
          scale: 1,
        },
      ],
      {
        duration: time,
        easing: 'ease-in-out',
        fill: 'forwards',
      },
    )
    animation.pause()
    ob.observe(el)
    map.set(el, animation)
  },
  unmounted(el) {
    ob.unobserve(el)
  },
}
export default slideIn
